from SimpleIndirectionBlock import SimpleIndirectionBlock
from DoubleIndirectionBlock import DoubleIndirectionBlock
from TripleIndirectionBlock import TripleIndirectionBlock



class INode(object):
    
    def __init__(self,anINodeId):
        self.id = anINodeId
        self.fileName = ""
        self.dataIndex = {}
        self.isFile = True
        self.dataIndexMax = 8
        self.isUsed = False
        self.simpleIndirectionIndex = []
        self.simpleIndirectionIndexMax = 4 
        self.doubleIndirectionIndex = []
        self.doubleIndirectionIndexMax = 2 
        self.tripleIndirectionIndex = [] 
        self.tripleIndirectionIndexMax = 2 
        self.dataFileCounter = 0 
        
        
    def getSimpleBlocks(self):
        return self.simpleIndirectionIndex
    
    def getDoubleBlocks(self):
        return self.doubleIndirectionIndex
    
    def getTripleBlocks(self):
        return self.tripleIndirectionIndex
    
    def getDataIndex(self):
        return self.dataIndex

        
    def addDataPointer(self,aPointer):
        if (8 > len(self.dataIndex)) :
            self.dataIndex [aPointer] = self.dataFileCounter + 1 
            self.incrementFileCounter()
        elif (self.simpleIndirectionIndexHasSpace()): 
                self.addDataPointerToSimpleIndirectionBlocks(aPointer)
        elif (self.doubleIndirectionIndexHasSpace()):
                self.addDataPointerToDoubleIndirectionBlocks(aPointer)     
        elif (self.tripleIndirectionIndexHasSpace()):
                self.addDataPointerToTripleIndirectionBlocks(aPointer)  

    def addDataPointer2(self,aPointer):
        if(8>len(self.dataIndex)):
            self.dataIndex[aPointer]= self.dataFileCounter + 1
            self.incrementFileCounter()
        elif (self.simpleIndirectionIndexHasSpace()):
            self.addDataPointerToSimpleIndirectionBlocks(aPointer)
        elif (self.simpleIndirectionIndexHasSpaceToANewBlock()):
            self.addsimpleIndirectionBlock(SimpleIndirectionBlock())
            self.addDataPointerToSimpleIndirectionBlocks(aPointer)
        elif (self.doubleIndirectionIndexHasSpace()):
            self.addDataPointerToDoubleIndirectionBlocks(aPointer)
        elif (self.doubleIndexHasSpaceToASimpleBlock()):
            self.addSimpleBlockToDoubleIndirectionIndex(SimpleIndirectionBlock())
            self.addDataPointerToDoubleIndirectionBlocks(aPointer)
        elif (self.doubleHasSpace()):
            self.addDoubleIndirectionBlock(DoubleIndirectionBlock())
            self.addSimpleBlockToDoubleIndirectionIndex(SimpleIndirectionBlock())
            self.addDataPointerToDoubleIndirectionBlocks(aPointer)
        elif (self.tripleIndirectionIndexHasSpace()):
            self.addDataPointerToTripleIndirectionBlocks(aPointer)
        elif (self.tripleIndexHasSpaceToASimpleBlock()):
            self.addSimpleBlockToTripleIndirectionIndex(SimpleIndirectionBlock()) 
            self.addDataPointerToTripleIndirectionBlocks(aPointer)
        elif (self.tripleIndexHasSpaceToADoubleBlock()):
            self.addDoubleBlockToTripleIndirectionIndex(DoubleIndirectionBlock())
            self.addSimpleBlockToTripleIndirectionIndex(SimpleIndirectionBlock())
            self.addDataPointerToTripleIndirectionBlocks(aPointer)
        elif (self.tripleHasSpace()):
            self.addTripleIndirectionBlock(TripleIndirectionBlock())
            self.addDoubleBlockToTripleIndirectionIndex(DoubleIndirectionBlock())
            self.addSimpleBlockToTripleIndirectionIndex(SimpleIndirectionBlock())
            self.addDataPointerToTripleIndirectionBlocks(aPointer)
            
            
            

    def tripleHasSpace(self):
        if (self.tripleIndirectionIndexMax > len(self.tripleIndirectionIndex)):
            return True
        return False
    
    def tripleIndexHasSpaceToASimpleBlock(self):
        for i in self.tripleIndirectionIndex:
            if i.hasSpaceToASimpleBlock():
                return True
        return False
    
    def tripleIndexHasSpaceToADoubleBlock(self):
        for i in self.tripleIndirectionIndex:
            if i.hasSpaceToABlock():
                return True
        return False
    
    def addSimpleBlockToTripleIndirectionIndex(self, aSimpleIndirectionBlock):
        if (self.tripleIndexHasSpaceToASimpleBlock()):
            for i in self.tripleIndirectionIndex:
                if i.hasSpaceToASimpleBlock():
                    i.addSimpleIndirectionBlock(aSimpleIndirectionBlock)
                    break
    
    def addDoubleBlockToTripleIndirectionIndex(self, aDoubleIndirectionBlock):
        if (self.tripleIndexHasSpaceToADoubleBlock()):
            for i in self.tripleIndirectionIndex:
                if i.hasSpaceToABlock():
                    i.addDoubleIndirectionBlock(aDoubleIndirectionBlock)
                    break
    
    def doubleIndexHasSpaceToASimpleBlock(self):
        for i in self.doubleIndirectionIndex:
            if i.hasSpaceToABlock():
                return True
        return False
    
    def addSimpleBlockToDoubleIndirectionIndex(self, aSimpleIndirectionBlock):
        if self.doubleIndexHasSpaceToASimpleBlock():
            for i in self.doubleIndirectionIndex:
                if i.hasSpaceToABlock():
                    i.addIndirectionBlock(aSimpleIndirectionBlock)
                    break
                
    def doubleHasSpace(self):
        if (self.doubleIndirectionIndexMax > len(self.doubleIndirectionIndex)):
            return True
        return False
                
    def simpleIndirectionIndexHasSpaceToANewBlock(self):
        if (self.simpleIndirectionIndexMax > len(self.simpleIndirectionIndex)):
            return True
        return False
    
    
    
    
    def setInode(self,aFileName,aBlockList):
        self.isUsed = True
        self.setName(aFileName)
        for i in range(len(aBlockList)):
            self.addDataPointer2(aBlockList[i])
    
    def getBlocks(self):
        listOfBlocks = []
        dataIndex = self.getBlocksFromDataIndex()
        simpleIndex = self.getBlocksFromSimpleIndex()
        doubleIndex = self.getBlocksFromDoubleIndex()
        tripleIndex = self.getBlocksFromTripleIndex()
        for i in dataIndex:
            listOfBlocks.append(i)
        for j in simpleIndex:
            listOfBlocks.append(j)
        for h in doubleIndex:
            listOfBlocks.append(h)
        for g in tripleIndex:
            listOfBlocks.append(g)
        return listOfBlocks
        
        
        
        
    def getBlocksFromDataIndex(self):
        listOfBlocks = []
        x = self.dataIndex.__iter__()
        listOfBlocks.extend(x)
        return listOfBlocks
    
    def getBlocksFromSimpleIndex(self):
        listOfBlocks = []
        for i in self.simpleIndirectionIndex:
            list = i.getBlocks()
            for j in list:
                listOfBlocks.append(j)
        return listOfBlocks
    
    def getBlocksFromDoubleIndex(self):
        listOfBlocks = []
        for i in self.doubleIndirectionIndex:
            list = i.getBlocks()
            for j in list:
                listOfBlocks.append(j)
        return listOfBlocks
    
    
    def getBlocksFromTripleIndex(self):
        listOfBlocks = []
        for i in self.tripleIndirectionIndex:
            list = i.getBlocks()
            for j in list:
                listOfBlocks.append(j)
        return listOfBlocks
    
    
    
    def setName(self,aName):
        self.fileName = aName
        
    def getFileName(self):
        return self.fileName
    
    def incrementFileCounter(self):
        self.dataFileCounter = self.dataFileCounter + 1
    
    def simpleIndirectionIndexHasSpace(self):
        if (self.simpleIndirectionIndex.__len__() < 1): #si no hay nada guardado, hay que crear el bloque
            return False
        else:
            for i in self.simpleIndirectionIndex:  
                    if (i.hasSpace()):
                        return True 
        return False 
                     
    def addDataPointerToSimpleIndirectionBlocks(self, aPointer):
        for d in self.simpleIndirectionIndex:
            if(d.hasSpace()):
                self.incrementFileCounter()
                d.addDataPointer(aPointer, self.dataFileCounter)
                break 
    
    def doubleIndirectionIndexHasSpace(self):
        for i in self.doubleIndirectionIndex: 
            if(i.hasSpace()): 
                return True 
        return False 

    def addDataPointerToDoubleIndirectionBlocks(self, aPointer):
        for d in self.doubleIndirectionIndex: 
            if(d.hasSpace()):
                self.incrementFileCounter()
                d.addDataPointer (aPointer,self.dataFileCounter) 
                
                break 
            
    def tripleIndirectionIndexHasSpace(self):
        for i in self.tripleIndirectionIndex:
            if i.hasSpace():
                return True
        return False
    
    def addDataPointerToTripleIndirectionBlocks(self, aPointer):
        for i in self.tripleIndirectionIndex:
            if i.hasSpace():
                self.incrementFileCounter()
                i.addDataPointer(aPointer, self.dataFileCounter)
                break
        
    #===========================================================================
    # Contains
    #===========================================================================
    
    def simpleIndexContains(self, aPointer):
        for i in self.simpleIndirectionIndex:
            if i.contains(aPointer):
                return True
        return False
    
    def doubleIndexContains(self, aPointer):
        for i in self.doubleIndirectionIndex:
            if i.contains(aPointer):
                return True
        return False
    
    def tripleIndexContains(self, aPointer):
        for i in self.tripleIndirectionIndex:
            if i.contains(aPointer):
                return True
        return False
    
    def contains(self, aPointer):
        if((self.dataIndex.__contains__(aPointer)) |( self.simpleIndexContains(aPointer)) | (self.doubleIndexContains(aPointer)) | (self.tripleIndexContains(aPointer))):
            return True
        else:
            return False

    #===========================================================================
    # Remove data pointers
    #===========================================================================
    
    def removeDataPointerFromSimpleIndex (self, aPointer):
        for i in self.simpleIndirectionIndex:
            if i.contains(aPointer):
                i.removeDataPointer(aPointer)
    
    def removeDataPointerFromDoubleIndex(self, aPointer):
        for i in self.doubleIndirectionIndex:
            if i.contains(aPointer):
                i.removeDataPointer(aPointer)
                
    def removeDataPointerFromTripleIndex(self,aPointer):
        for i in self.tripleIndirectionIndex:
            if i.contains(aPointer):
                i.removeDataPointer(aPointer)
    
    def removeDataPointer(self, aPointer):
        if self.contains(aPointer):
            if(self.dataIndex.__contains__(aPointer)):
                del(self.dataIndex)[aPointer]
            elif (self.simpleIndexContains(aPointer)):
                self.removeDataPointerFromSimpleIndex(aPointer)
            elif (self.doubleIndexContains(aPointer)):
                self.removeDataPointerFromDoubleIndex(aPointer)
            elif (self.tripleIndexContains(aPointer)):
                self.removeDataPointerFromTripleIndex(aPointer)
                
    
    
    #===========================================================================
    # Remove indirection blocks
    #===========================================================================
    
    def removeTripleIndirectionBlock(self, aTripleIndirectionBlock):
        if (self.tripleIndirectionIndex.__contains__(aTripleIndirectionBlock)):
            self.tripleIndirectionIndex.remove(aTripleIndirectionBlock)
            
    def removeDoubleIndirectionBlock(self, aDoubleIndirectionBlock):
        if (self.doubleIndirectionIndex.__contains__(aDoubleIndirectionBlock)):
            self.doubleIndirectionIndex.remove(aDoubleIndirectionBlock)
    
    def removeSimpleIndirectionBlock(self, aSimpleIndirectionBlock):
        if (self.simpleIndirectionIndex.__contains__(aSimpleIndirectionBlock)):
            self.simpleIndirectionIndex.remove(aSimpleIndirectionBlock)
    
    
    #===========================================================================
    # Add indirection blocks
    #===========================================================================
    
    
    
    def addsimpleIndirectionBlock(self,aSimpleIndirectionBlock):
        if (self.simpleIndirectionIndexMax > len(self.simpleIndirectionIndex)) :
            self.simpleIndirectionIndex.append(aSimpleIndirectionBlock)
       
    def addDoubleIndirectionBlock(self,aDoubleIndirectionBlock):
        if (self.doubleIndirectionIndexMax > len(self.doubleIndirectionIndex)) :
            self.doubleIndirectionIndex.append(aDoubleIndirectionBlock)
        
    def addTripleIndirectionBlock(self,aTripleIndirectionBlock):
        if (self.tripleIndirectionIndexMax > len(self.tripleIndirectionIndex)) :
            self.tripleIndirectionIndex.append(aTripleIndirectionBlock)
            
    
    
    